package com.github.dongglin.smart.spring.boot.plus.core.framework.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.diboot.core.binding.Binder;
import com.github.dongglin.smart.spring.boot.plus.common.constant.CommonConstant;
import com.github.dongglin.smart.spring.boot.plus.common.exception.QueryNotFoundException;
import com.github.dongglin.smart.spring.boot.plus.core.framework.basemapper.OptionalBaseMapper;
import com.github.dongglin.smart.spring.boot.plus.core.framework.pager.BasePageQuery;
import com.github.dongglin.smart.spring.boot.plus.core.framework.pager.OrderByItem;
import com.github.dongglin.smart.spring.boot.plus.core.framework.pager.PageResult;
import com.github.dongglin.smart.spring.boot.plus.core.framework.service.OptionalBaseService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @param <M> mapper
 * @param <T> entity
 * @author DongGL
 * @date 2023/9/20 15:57
 * 基础service通用方法封装
 */
@SuppressWarnings({"DuplicatedCode", "unused"})
public class OptionalBaseServiceImpl<M extends OptionalBaseMapper<T>, T> extends ServiceImpl<M, T> implements OptionalBaseService<T> {


    /**
     * 处理分页
     *
     * @param basePageQuery 分页参数
     */
    @Override
    public void handlePage(BasePageQuery basePageQuery) {
        handlePage(basePageQuery, null);
    }

    /**
     * 处理分页
     *
     * @param basePageQuery  分页参数
     * @param defaultOrderBy 排序
     */
    @Override
    public void handlePage(BasePageQuery basePageQuery, String defaultOrderBy) {
        String orderBy = defaultOrderBy;
        Integer pageIndex = CommonConstant.DEFAULT_PAGE_INDEX;
        Integer pageSize = CommonConstant.DEFAULT_PAGE_SIZE;
        if (basePageQuery != null) {
            pageIndex = basePageQuery.getPageIndex();
            pageSize = basePageQuery.getPageSize();
            // 判断参数中是否有排序
            OrderByItem orderByItem = basePageQuery.getOrderBy();
            if (orderByItem != null) {
                String paramOrderBy = orderByItem.getOrderBy();
                if (StringUtils.isNotBlank(paramOrderBy)) {
                    orderBy = paramOrderBy;
                }
            }
        }
        PageHelper.startPage(pageIndex, pageSize, orderBy);
    }

    /**
     * 根据 Wrapper 条件，查询总记录数 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T
     */
    @Override
    public Long getCountOptionalOrElseThrow(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().getCount(queryWrapper).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 Wrapper 条件，查询总记录数 如果不存在抛出对象不存在 返回0
     *
     * @param queryWrapper 实体对象封装操作类
     * @return T
     */
    @Override
    public Long getCountOptionalOrElseZero(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().getCount(queryWrapper).orElse(0L);
    }

    /**
     * 查询指定字段值数量 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public Long selectCountOptionalOrElseThrow(String field, Object value) {
        return this.getBaseMapper().selectCount(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询指定字段值数量 查询总记录数 如果不存在抛出对象不存在 返回0
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public Long selectCountOptionalOrElseZero(String field, Object value) {
        return this.getBaseMapper().selectCount(field, value).orElse(0L);
    }


    /**
     * 查询指定字段值数量 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public Long selectCountOptionalOrElseThrow(SFunction<T, ?> field, Object value) {
        return this.getBaseMapper().selectCount(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询指定字段值数量 如果不存在抛出对象不存在 返回0
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public Long selectCountOptionalOrElseZero(SFunction<T, ?> field, Object value) {
        return this.getBaseMapper().selectCount(field, value).orElse(0L);
    }

    // ======================================= 查询一个 ========================================


    /**
     * 根据 ID 查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param id 主键ID
     * @return T t
     */
    @Override
    public T getByIdOptionalOrElseThrow(Serializable id) {
        return this.getBaseMapper().getById(id).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 ID 查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param id      主键ID
     * @param voClass 包含对象状态，比如VO
     * @return T t
     */
    @Override
    public <VO> VO getByIdViewObjectOptionalOrElseThrow(Serializable id, Class<VO> voClass) {
        T entity = this.getBaseMapper().getById(id).orElseThrow(QueryNotFoundException::new);
        // 绑定
        return Binder.convertAndBindRelations(entity, voClass);
    }


    /**
     * 根据 entity 条件，查询一条记录  如果不存在抛出对象不存在 @QueryNotFoundException
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public T getOneOptionalOrElseThrow(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().getOne(queryWrapper).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 ID 查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param voClass      需要绑定的对象类型
     * @return T t
     */
    @Override
    public <VO> VO getViewObjectOptionalOrElseThrow(Wrapper<T> queryWrapper, Class<VO> voClass) {
        T entity = this.getBaseMapper().getOne(queryWrapper).orElseThrow(QueryNotFoundException::new);
        // 绑定
        return Binder.convertAndBindRelations(entity, voClass);
    }

    /**
     * 查询一个
     *
     * @param field field
     * @param value value @return T
     * @return T t
     */
    @Override
    public T getOneOptionalOrElseThrow(String field, Object value) {
        return this.getBaseMapper().getOne(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询一个
     *
     * @param field   field
     * @param value   value
     * @param voClass voClass
     * @return T t
     */
    @Override
    public <VO> VO getOneViewObjectOptionalOrElseThrow(String field, Object value, Class<VO> voClass) {
        T entity = this.getBaseMapper().getOne(field, value).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(entity, voClass);
    }

    /**
     * 查询一个
     *
     * @param field field
     * @param value value @return T
     * @return T t
     */
    @Override
    public T getOneOptionalOrElseThrow(SFunction<T, ?> field, Object value) {
        return this.getBaseMapper().getOne(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询一个
     *
     * @param field field
     * @param value value
     * @return T t
     */
    @Override
    public <VO> VO getOneViewObjectOptionalOrElseThrow(SFunction<T, ?> field, Object value, Class<VO> voClass) {
        T entity = this.getBaseMapper().getOne(field, value).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(entity, voClass);
    }

    /**
     * 查询一个
     *
     * @param field1 field1
     * @param value1 value1
     * @param field2 field2
     * @param value2 value2
     * @return T t
     */
    @Override
    public T getTwoOptionalOrElseThrow(String field1, Object value1, String field2, Object value2) {
        return this.getBaseMapper().getTwo(field1, value1, field2, value2).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询一个
     *
     * @param field1 field1
     * @param value1 value1
     * @param field2 field2
     * @param value2 value2
     * @return T t
     */
    @Override
    public <VO> VO getOneViewObjectOptionalOrElseThrow(String field1, Object value1, String field2, Object value2, Class<VO> voClass) {
        T entity = this.getBaseMapper().getTwo(field1, value1, field2, value2).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(entity, voClass);
    }

    /**
     * 查询一个
     *
     * @param field1 field1
     * @param value1 value1
     * @param field2 field2
     * @param value2 value2
     * @return T t
     */
    @Override
    public T getTwoOptionalOrElseThrow(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
        return this.getBaseMapper().getTwo(field1, value1, field2, value2).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询一个
     *
     * @param field1 field1
     * @param value1 value1
     * @param field2 field2
     * @param value2 value2
     * @return T t
     */
    @Override
    public <VO> VO getTwoOptionalOrElseThrow(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2, Class<VO> voClass) {
        T entity = this.getBaseMapper().getTwo(field1, value1, field2, value2).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(entity, voClass);
    }

    /**
     * 查询（根据ID 批量查询） 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     * @return T t
     */
    @Override
    public List<T> listBatchIdsOptionalOrElseThrow(Collection<? extends Serializable> idList) {
        return this.getBaseMapper().listBatchIds(idList).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询（根据ID 批量查询） 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     * @return T t
     */
    @Override
    public <VO> List<VO> listBatchIdsViewOptionalOrElseThrow(Collection<? extends Serializable> idList, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 查询（根据ID 批量查询） 如果不存在抛出对象不存在 返回empty
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     * @return T t
     */
    @Override
    public List<T> listBatchIdsOptionalOrElseEmpty(Collection<? extends Serializable> idList) {
        return this.getBaseMapper().listBatchIds(idList).orElse(Collections.emptyList());
    }

    /**
     * 查询（根据ID 批量查询） 如果不存在抛出对象不存在 返回empty
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     * @return T t
     */
    @Override
    public <VO> List<VO> listBatchIdsViewOptionalOrElseEmpty(Collection<? extends Serializable> idList, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 根据 entity 条件，查询全部记录 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseThrow(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().list(queryWrapper).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 entity 条件，查询全部记录 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseThrow(Wrapper<T> queryWrapper, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(queryWrapper).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 根据 entity 条件，查询全部记录  如果不存在抛出对象不存在 返回empty
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseEmpty(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().list(queryWrapper).orElse(Collections.emptyList());
    }

    /**
     * 根据 entity 条件，查询全部记录  如果不存在抛出对象不存在 返回empty
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseEmpty(Wrapper<T> queryWrapper, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(queryWrapper).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public List<T> listOptionalOrElseThrow(String field, Object value) {
        return this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseThrow(String field, Object value, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public List<T> listOptionalOrElseEmpty(String field, Object value) {
        return this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseEmpty(String field, Object value, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException *
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public List<T> listOptionalOrElseThrow(SFunction<T, ?> field, Object value) {
        return this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException *
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseThrow(SFunction<T, ?> field, Object value, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty *
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public List<T> listOptionalOrElseEmpty(SFunction<T, ?> field, Object value) {
        return this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty *
     *
     * @param field field
     * @param value value
     * @return T
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseEmpty(SFunction<T, ?> field, Object value, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException *
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseThrow(String field, Collection<?> values) {
        return this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在  返回empty
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseEmpty(String field, Collection<?> values) {
        return this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
    }

    /**
     * 列表查询 如果不存在抛出对象不存在  返回empty
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseThrow(String field, Collection<?> values, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseThrow(SFunction<T, ?> field, Collection<?> values) {
        return this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 列表查询 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseEmpty(String field, Collection<?> values, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }


    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty *
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public List<T> listOptionalOrElseEmpty(SFunction<T, ?> field, Collection<?> values) {
        return this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
    }

    /**
     * @param field   field
     * @param values  values
     * @param voClass v
     * @param <VO>    vo
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseEmpty(SFunction<T, ?> field, Collection<?> values, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }


    /**
     * 列表查询 如果不存在抛出对象不存在 返回empty *
     *
     * @param field  field
     * @param values values
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewOptionalOrElseThrow(SFunction<T, ?> field, Collection<?> values, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 查询（根据 columnMap 条件） 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param columnMap 表字段 map 对象
     * @return T t
     */
    @Override
    public List<T> listByMapsOptionalOrElseThrow(Map<String, Object> columnMap) {
        return this.getBaseMapper().listByMaps(columnMap).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 查询（根据 columnMap 条件） 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param columnMap 表字段 map 对象
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewByMapsOptionalOrElseThrow(Map<String, Object> columnMap, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElseThrow(QueryNotFoundException::new);
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 查询（根据 columnMap 条件） 如果不存在抛出对象不存在 返回empty
     *
     * @param columnMap 表字段 map 对象
     * @return T t
     */
    @Override
    public List<T> listByMapsOptionalOrElseEmpty(Map<String, Object> columnMap) {
        return this.getBaseMapper().listByMaps(columnMap).orElse(Collections.emptyList());
    }

    /**
     * 查询（根据 columnMap 条件） 如果不存在抛出对象不存在 返回empty
     *
     * @param columnMap 表字段 map 对象
     * @return T t
     */
    @Override
    public <VO> List<VO> listViewByMapsOptionalOrElseEmpty(Map<String, Object> columnMap, Class<VO> voClass) {
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElse(Collections.emptyList());
        return Binder.convertAndBindRelations(list, voClass);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录 如果不存在抛出对象不存在 @QueryNotFoundException
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<Map<String, Object>> mapsOptionalOrElseThrow(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().maps(queryWrapper).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录  如果不存在抛出对象不存在 返回empty
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<Map<String, Object>> mapsOptionalOrElseEmpty(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().maps(queryWrapper).orElse(Collections.emptyList());
    }

    /**
     * 根据 Wrapper 条件，查询全部记录 如果不存在抛出对象不存在 @QueryNotFoundException
     * <p>注意： 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<Object> listObjsOptionalOrElseThrow(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().listObjs(queryWrapper).orElseThrow(QueryNotFoundException::new);
    }

    /**
     * 根据 Wrapper 条件，查询全部记录 如果不存在抛出对象不存在 返回empty
     * <p>注意： 只返回第一个字段的值</p>
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return T t
     */
    @Override
    public List<Object> listObjsOptionalOrElseEmpty(Wrapper<T> queryWrapper) {
        return this.getBaseMapper().listObjs(queryWrapper).orElse(Collections.emptyList());
    }

    /**
     * @param idList    主键ID列表(不能为 null 以及 empty)
     * @param pageQuery q
     * @return T t
     */
    @Override
    public PageResult<T> pagerListBatchIdsOptionalOrElseThrow(Collection<? extends Serializable> idList, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param idList    主键ID列表(不能为 null 以及 empty)
     * @param voClass   t
     * @param pageQuery t
     * @param <VO>      vo
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListBatchIdsViewOptionalOrElseThrow(Collection<? extends Serializable> idList, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param idList    主键ID列表(不能为 null 以及 empty)
     * @param pageQuery
     * @return t
     */
    @Override
    public PageResult<T> pagerListBatchIdsOptionalOrElseEmpty(Collection<? extends Serializable> idList, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param idList    主键ID列表(不能为 null 以及 empty)
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      vo
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListBatchIdsViewOptionalOrElseEmpty(Collection<? extends Serializable> idList, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listBatchIds(idList).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param pageQuery    q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseThrow(Wrapper<T> queryWrapper, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(queryWrapper).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param voClass      v
     * @param pageQuery    p
     * @param <VO>         vo
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseThrow(Wrapper<T> queryWrapper, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(queryWrapper).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param pageQuery    q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseEmpty(Wrapper<T> queryWrapper, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(queryWrapper).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @param voClass      b
     * @param pageQuery    q
     * @param <VO>         v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseEmpty(Wrapper<T> queryWrapper, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(queryWrapper).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseThrow(String field, Object value, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param voClass   b
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseThrow(String field, Object value, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseEmpty(String field, Object value, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseEmpty(String field, Object value, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseThrow(SFunction<T, ?> field, Object value, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseThrow(SFunction<T, ?> field, Object value, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseEmpty(SFunction<T, ?> field, Object value, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param value     value
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseEmpty(SFunction<T, ?> field, Object value, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, value).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseThrow(String field, Collection<?> values, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseThrow(String field, Collection<?> values, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageResult(voList);
    }

    /**
     * @param field     field
     * @param values    values
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseEmpty(String field, Collection<?> values, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListOptionalOrElseEmpty(String field, Collection<?> values, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseThrow(SFunction<T, ?> field, Collection<?> values, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseThrow(SFunction<T, ?> field, Collection<?> values, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListOptionalOrElseEmpty(SFunction<T, ?> field, Collection<?> values, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param field     field
     * @param values    values
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewOptionalOrElseEmpty(SFunction<T, ?> field, Collection<?> values, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().list(field, values).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param columnMap 表字段 map 对象
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListByMapsOptionalOrElseThrow(Map<String, Object> columnMap, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElseThrow(QueryNotFoundException::new);
        return pageResult(list);
    }

    /**
     * @param columnMap 表字段 map 对象
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewByMapsOptionalOrElseThrow(Map<String, Object> columnMap, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElseThrow(QueryNotFoundException::new);
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param columnMap 表字段 map 对象
     * @param pageQuery q
     * @return t
     */
    @Override
    public PageResult<T> pagerListByMapsOptionalOrElseEmpty(Map<String, Object> columnMap, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElse(Collections.emptyList());
        return pageResult(list);
    }

    /**
     * @param columnMap 表字段 map 对象
     * @param voClass   v
     * @param pageQuery q
     * @param <VO>      v
     * @return t
     */
    @Override
    public <VO> PageResult<VO> pagerListViewByMapsOptionalOrElseEmpty(Map<String, Object> columnMap, Class<VO> voClass, BasePageQuery pageQuery) {
        handlePage(pageQuery, OrderByItem.desc("id"));
        List<T> list = this.getBaseMapper().listByMaps(columnMap).orElse(Collections.emptyList());
        List<VO> voList = Binder.convertAndBindRelations(list, voClass);
        return pageViewResult(voList, list);
    }

    /**
     * @param list l
     * @param <T>  t
     * @return t
     */
    public static <T> PageResult<T> pageResult(List<T> list) {
        PageResult<T> pageResult = new PageResult<T>();
        if (CollectionUtil.isNotEmpty(list)) {
            pageResult.setTotal(((Page<?>) list).getTotal());
            pageResult.setPage(((Page<?>) list).getPageNum());
            pageResult.setPages(((Page<?>) list).getPages());
            pageResult.setPageSize(((Page<?>) list).getPageSize());
        }
        pageResult.setRecords(list);
        return pageResult;
    }

    /**
     * @param list   list
     * @param relist relist
     * @param <VO>   vo
     * @return t
     */
    public static <VO> PageResult<VO> pageViewResult(List<VO> list, List<?> relist) {
        PageResult<VO> pageResult = new PageResult<VO>();
        if (CollectionUtil.isNotEmpty(relist)) {
            pageResult.setTotal(((Page<?>) relist).getTotal());
            pageResult.setPage(((Page<?>) relist).getPageNum());
            pageResult.setPages(((Page<?>) relist).getPages());
            pageResult.setPageSize(((Page<?>) relist).getPageSize());
        }
        pageResult.setRecords(list);
        return pageResult;
    }

}
